/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.pz.net;

import java.io.IOException;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SocketChannel;
import java.util.LinkedList;
import java.util.List;

import org.pz.net.shared.Command;
import static org.pz.net.util.BufferHelper.*;

/**
 *
 * @author Jannek
 */
public abstract class MasterServerLink {
    
    private static SocketAddress masterAddress = null;
    private static ByteBuffer buffer = ByteBuffer.allocate(10000);
    
    public static void setMasterAddress(SocketAddress address)
    {
        masterAddress = address;
    }
    
    private static void connectToMasterServer() throws IOException
    {
        SocketChannel channel = SocketChannel.open(masterAddress);
        buffer.flip();
        channel.write(buffer);
        buffer.clear();
        channel.read(buffer);
        buffer.flip();
    }
    
    public static Connection createClient(ByteBuffer data, boolean asHost) throws IOException, PzNetException
    {
        buffer.clear();
        put(asHost ? Command.CREATE_HOST : Command.CREATE_CLIENT, buffer);
        buffer.putShort((short) data.remaining());
        buffer.put(data);
        
        connectToMasterServer();
        
        if (getCommand(buffer) != Command.FROM_MASTER)
            throw new PzNetException("Corrupted data received by server.");
        
        switch (getCommand(buffer))
        {
            case CLIENT_CREATED:
                int id = buffer.getInt();
                int key = buffer.getInt();
                Connection connection = new Connection(id, key, asHost);
                if (connection.isUdpConfirmed())
                    return connection;
                
                throw new PzNetException("Udp port was not confirmed.");
                
            case ILLEGAL_ACTION:
                throw new PzNetException("Command not permitted by server.");
            default:
                throw new PzNetException("Corrupted data received by server.");
        }
    }
    
    public static List<HostInfo> getHostList(ByteBuffer filter) throws IOException
    {
        buffer.clear();
        put(Command.GET_HOST_LIST, buffer);
        buffer.putShort((short) filter.remaining());
        buffer.put(filter);
        
        connectToMasterServer();
        
        if (getCommand(buffer) != Command.FROM_MASTER)
            return null;
        
        List<HostInfo> list = new LinkedList<HostInfo>();
        while (buffer.remaining() > 12) // id + name length + name + max + players + ping
        {
            int id = buffer.getInt();
            String name = getString(buffer);
            short maxPlayer = buffer.getShort();
            short players = buffer.getShort();
            short ping = buffer.getShort();
            list.add(new HostInfo(id, name, maxPlayer, players, ping));
        }
        
        return list;
    }
    
    public static Other connectToHost(HostInfo host, int clientId, int clientKey)
    {
        
    }
    
    public static List<Other> getNewClients(int hostId, int hostKey)
    {
        
    }
    
    
    public static void updateUdp(DatagramChannel udpChannel, ByteBuffer data) throws IOException
    {
        udpChannel.send(data, masterAddress);
    }
}
